﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;
using System.Diagnostics;
using System.IO;

using BasePlatformNet;
using BasePlatformCommon.devChain;
using BasePlatformCommon;

namespace L9SubSet {
    public partial class Form_SubUpdate : Form {
        private string versionStr = "分控升级";		// 窗口标题

        private bool debugSwich = false;			// 调试日志开关

        private ArrayList deviceInfoList = null;	// 分控列表

        private int maxSubCtrlNum = 255;			// 最大分控数量

        private int currentTestedNum = 0;			// 当前检测到的分控数量

        private int lastTestedNum = 0;				// 上一次完整检测后, 检测到的分控数量

        private Random myRandom = null;				// 随机数生成器

        private string rbfFileName = "";			// .rbf 文件路径 + 文件名

        private string rbfSafeFileName = "";		// .rbf 文件名

        private Color selectColor = Color.FromArgb(255, 255, 190);	// 选中色

        private ArrayList updateSubEquDepth = null;				// 要升级的分控

        private DeviceType target = DeviceType.SubControl;			// 升级目标 - 默认分控

        private ProgramType p_type = ProgramType.App;			// 升级目标 - 默认分控

        private int updateMode = 1;					// 升级操作模式：0-串行模式, 1-并行模式（默认）, 2-全局模式

        private int mcuModeSwitchInterval = 5000;      // mcu升级模式切换后延时

        private byte[] dataBuffOrign;				// 数据缓冲区 - 升级用

        private byte[] dataBuff1;					// 数据缓冲区1 - 升级用

        private byte[] dataBuff2;					// 数据缓冲区2 - 升级用

        private byte[] checkBuff;					// 检查核对数据区	- 升级用

        private bool forceStopUpdate = false;		// 强制停止升级

        private bool forceExit = false;				// 强制退出程序

        private int checkTimeSpan = 10;				// 发送检查包时间间隔

        private int currentDeviceIndex = -1;		// 当前选中的网络设备索引

        private BaseCoreNet baseCoreNet = null;		// 网口通信平台

        private int logPrintNum = 0;				// 日志打印数量

        private bool cancelForceInitial = false;	// 强制进入底层取消标记

        private string lastPath_RbfFile = "";		// .rbf 文件路径暂存

        #region 委托定义与声明

        // 更新分控详细信息列表
        public delegate void UpdateDeviceDetailDelegate();
        private UpdateDeviceDetailDelegate updateDeviceDetailDelegate;

        // 更新分控详细信息列表 - 单行信息
        private delegate void RefreshRowInfoDelegate(int rowNum, int cellNum, string value);
        private RefreshRowInfoDelegate refreshRowInfoDelegate;

        // 更新整体进度标签
        private delegate void RefreshTotalProcessLabelDelegate(string value);
        private RefreshTotalProcessLabelDelegate refreshTotalProcessLabelDelegate;

        // 更新当前操作标签
        private delegate void UpdateCurrentOperLabelDelegate(string value);
        private UpdateCurrentOperLabelDelegate updateCurrentOperLabelDelegate;

        // 更新进度条
        private delegate void SetProgressBarValueDelegate(int value);
        private SetProgressBarValueDelegate setProgressBarValueDelegate;

        // 复位分控
        private delegate void ResetSubControlOperDelegate();
        private ResetSubControlOperDelegate resetSubControlOperDelegate;

        // 升级操作前禁用界面按钮
        private delegate void DisableButtonsBeforeUpdateDelegate();
        private DisableButtonsBeforeUpdateDelegate disableButtonsBeforeUpdateDelegate;

        // 升级操作后恢复界面按钮
        private delegate void EnableButtonsAfterUpdateDelegate();
        private EnableButtonsAfterUpdateDelegate enableButtonsAfterUpdateDelegate;

        // 打印日志
        private delegate void TypeLogDelegate(string str);
        private TypeLogDelegate typeLogDelegate;

        #endregion 委托定义与声明

        private string section = "SubUpdate";		// 多语言文件配置节名称

        private string tip = "提示";					// MessageBox 题头

        private bool initDone = false;				// 初始化完成标志

        /*****************************************************************************************/

        // 构造函数
        public Form_SubUpdate(BaseCoreNet baseCoreNetExt, int activeDeviceIndex, bool testFlag = false) {
            currentDeviceIndex = activeDeviceIndex;

            InitializeComponent();

            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
            this.Font = new System.Drawing.Font(this.Font.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Pixel, ((byte)(134)));

            initEnvironment(baseCoreNetExt, testFlag);
        }

        // 初始化运行环境
        private void initEnvironment(BaseCoreNet baseCoreNetExt, bool testFlag = false) {
            this.Text = versionStr;

            myRandom = new Random();

            // 初始化网络设备
            initDevice(baseCoreNetExt);

            // 禁止用户添加新行
            infoDataView.AllowUserToAddRows = false;

            deviceInfoList = new ArrayList();
            for (int k = 0; k < maxSubCtrlNum + 1; k++) {
                SubEquInfo info = new SubEquInfo(k, false, "", -1, DeviceType.SubControl);
                deviceInfoList.Add(info);
                infoDataView.Rows.Add(info.id, info.needUpdate, info.typeStr, info.firmwareVersion, " --");
                infoDataView.Rows[k].Visible = false;
            }

            // 委托实例化
            updateDeviceDetailDelegate = new UpdateDeviceDetailDelegate(updateDeviceDetail);
            refreshRowInfoDelegate = new RefreshRowInfoDelegate(refreshRowInfo);
            refreshTotalProcessLabelDelegate = new RefreshTotalProcessLabelDelegate(refreshTotalProcessLabel);
            updateCurrentOperLabelDelegate = new UpdateCurrentOperLabelDelegate(refreshCurrentOperLabel);
            setProgressBarValueDelegate = new SetProgressBarValueDelegate(setProgressBarValue);
            resetSubControlOperDelegate = new ResetSubControlOperDelegate(resetAllSubEquControllers);
            disableButtonsBeforeUpdateDelegate = new DisableButtonsBeforeUpdateDelegate(disableButtonsBeforeUpdate);
            enableButtonsAfterUpdateDelegate = new EnableButtonsAfterUpdateDelegate(enableButtonsAfterUpdate);
            typeLogDelegate = new TypeLogDelegate(typeLog);

            checkBuff = new byte[256];

            FPGAradioButton.Checked = true;

            // 设置本地化语言
            if (LanguageOper.available == true) {
                setLanguageText();
            }

            subRadioButton.Checked = true;

            // 测试模式隐藏程序模式选择，显示当前程序说明
            showTestEnable(testFlag);

            initDone = true;
        }

        // 设置本地化语言
        public void setLanguageText() {
            if (LanguageOper.available == false) {
                return;
            }

            LanguageOper.SetCurrentCulture();

            tip = LanguageOper.ReadValue("Common", "tipStr");

            // 界面控件文字
            this.Text = LanguageOper.ReadValue(section, "subUpdate.Text");
            firmLabel.Text = LanguageOper.ReadValue(section, "firmLabel.Text");
            openButton.Text = LanguageOper.ReadValue(section, "openButton.Text");
            debugCheckBox.Text = LanguageOper.ReadValue(section, "debugCheckBox.Text");
            clearLogButton.Text = LanguageOper.ReadValue(section, "clearLogButton.Text");
            selectAllButton.Text = LanguageOper.ReadValue(section, "selectAllButton.Text");
            selectNoneButton.Text = LanguageOper.ReadValue(section, "selectNoneButton.Text");
            reverseButton.Text = LanguageOper.ReadValue(section, "reverseButton.Text");
            procLabel1.Text = LanguageOper.ReadValue(section, "procLabel1.Text");
            procLabel2.Text = LanguageOper.ReadValue(section, "procLabel2.Text");
            operLabel.Text = LanguageOper.ReadValue(section, "operLabel.Text");
            forceInitialButton.Text = LanguageOper.ReadValue(section, "forceInitialButton.Text");
            resetAllButton.Text = LanguageOper.ReadValue(section, "resetAllButton.Text");
            refreshSubInfoButton.Text = LanguageOper.ReadValue(section, "refreshSubInfoButton.Text");
            modeLabel.Text = LanguageOper.ReadValue(section, "modeLabel.Text");
            serialRadioButton.Text = LanguageOper.ReadValue(section, "serialRadioButton.Text");
            paraRadioButton.Text = LanguageOper.ReadValue(section, "paraRadioButton.Text");
            totalRadioButton.Text = LanguageOper.ReadValue(section, "totalRadioButton.Text");
            useUDPCheckBox.Text = LanguageOper.ReadValue(section, "useUDPCheckBox.Text");
            updateButton.Text = LanguageOper.ReadValue(section, "updateButton.Text");
            configTimeheckBox.Text = LanguageOper.ReadValue(section, "configTimeheckBox.Text");
            eraseLabel.Text = LanguageOper.ReadValue(section, "eraseLabel.Text");
            updateLabel.Text = LanguageOper.ReadValue(section, "updateLabel.Text");
            checkLabel.Text = LanguageOper.ReadValue(section, "checkLabel.Text");
            posLabel.Text = LanguageOper.ReadValue(section, "posLabel.Text");
            rbfLabel.Text = LanguageOper.ReadValue(section, "rbfLabel.Text");
            clearRBFTextButton.Text = LanguageOper.ReadValue(section, "clearRBFTextButton.Text");
            reReadButton.Text = LanguageOper.ReadValue(section, "reReadButton.Text");
            refreshButton.Text = LanguageOper.ReadValue(section, "refreshButton.Text");
            effectConfigButton.Text = LanguageOper.ReadValue(section, "effectConfigButton.Text");
            targetLabel.Text = LanguageOper.ReadValue(section, "targetLabel.Text");
            subRadioButton.Text = LanguageOper.ReadValue(section, "subRadioButton.Text");
            equRadioButton.Text = LanguageOper.ReadValue(section, "equRadioButton.Text");
            lblType.Text = LanguageOper.ReadValue(section, "lblType.Text");
            lblProgram.Text = LanguageOper.ReadValue(section, "lblProgram.Text");
            appRadioButton.Text = LanguageOper.ReadValue(section, "appRadioButton.Text");
            testRadioButton.Text = LanguageOper.ReadValue(section, "testRadioButton.Text");
            bootRadioButton.Text = LanguageOper.ReadValue(section, "bootRadioButton.Text");

            if (LanguageOper.LocalLanguage != LanguageEnum.EN) {
                serialRadioButton.Location = new Point(71, 7);
                paraRadioButton.Location = new Point(121, 7);
                totalRadioButton.Location = new Point(172, 7);
                eraseLabel.Location = new Point(119, 15);
                updateLabel.Location = new Point(258, 15);
                checkLabel.Location = new Point(461, 15);
                depthRadioButton1.Location = new Point(100, 6);
                depthRadioButton2.Location = new Point(173, 6);
                procLabel1.Location = new Point(261, 488);
                subRadioButton.Location = new Point(48, 4);
                equRadioButton.Location = new Point(100, 4);
            } else {
                serialRadioButton.Location = new Point(41, 7);
                paraRadioButton.Location = new Point(105, 7);
                totalRadioButton.Location = new Point(177, 7);
                eraseLabel.Location = new Point(132, 15);
                updateLabel.Location = new Point(249, 15);
                checkLabel.Location = new Point(458, 15);
                depthRadioButton1.Location = new Point(80, 6);
                depthRadioButton2.Location = new Point(153, 6);
                procLabel1.Location = new Point(272, 488);
                subRadioButton.Location = new Point(56, 4);
                equRadioButton.Location = new Point(108, 4);
            }

            // Tab 页与表格列头
            tabControl1.TabPages[0].Text = LanguageOper.ReadValue(section, "tabPages.Text.0");
            tabControl1.TabPages[1].Text = LanguageOper.ReadValue(section, "tabPages.Text.1");
            tabControl1.TabPages[2].Text = LanguageOper.ReadValue(section, "tabPages.Text.2");
            infoDataView.Columns[0].HeaderText = LanguageOper.ReadValue(section, "headText.0");
            infoDataView.Columns[1].HeaderText = LanguageOper.ReadValue(section, "headText.1");
            infoDataView.Columns[2].HeaderText = LanguageOper.ReadValue(section, "headText.2");
            infoDataView.Columns[3].HeaderText = LanguageOper.ReadValue(section, "headText.3");
            infoDataView.Columns[4].HeaderText = LanguageOper.ReadValue(section, "headText.4");
            infoDataView.Columns[5].HeaderText = LanguageOper.ReadValue(section, "headText.5");

            updateDeviceDetail();
        }

        // 初始化网口通信平台
        private void initDevice(BaseCoreNet baseCoreNetExt) {
            baseCoreNet = baseCoreNetExt;
            baseCoreNet.WriteFlashStateUpdated += writeFlashStateUpdated;
            baseCoreNet.ReadFlashStateUpdated += readFlashStateUpdated;
        }

        #region 业务逻辑

        // 重置检测环境
        private void resetDetectEnvironment() {
            for (int k = 0; k < maxSubCtrlNum + 1; k++) {
                infoDataView.Rows[k].Visible = false;
                infoDataView.Rows[k].DefaultCellStyle.BackColor = Color.White;
                ((DataGridViewCheckBoxCell)infoDataView.Rows[k].Cells[1]).Value = false;
                infoDataView.Rows[k].Cells[2].Value = "--";
                infoDataView.Rows[k].Cells[3].Value = "--";
                infoDataView.Rows[k].Cells[4].Value = "--";
            }

            if (updateSubEquDepth != null) {
                updateSubEquDepth.Clear();
            }

            deviceInfoList = new ArrayList();
            for (int k = 0; k < maxSubCtrlNum + 1; k++) {
                SubEquInfo info = new SubEquInfo(k, false, "", -1, DeviceType.SubControl);
                deviceInfoList.Add(info);
            }

            updateProgressBar.Value = 0;
            totalProcessLabel.Text = "0 / 0";
            updateStatusLabel.Text = "0 %";
        }

        // 【委托实现】更新设备详细信息列表界面
        private void updateDeviceDetail() {
            typeLog("maxSubCtrlNum = " + maxSubCtrlNum + ", currentTestedNum = " + currentTestedNum);

            for (int k = 0; k < maxSubCtrlNum + 1; k++) {
                infoDataView.Rows[k].Visible = false;
                infoDataView.Rows[k].DefaultCellStyle.BackColor = Color.White;
            }

            string text = "底层：";
            if (LanguageOper.available == true) {
                text = LanguageOper.ReadValue(section, "str.0");
            }

            for (int k = 1; k <= currentTestedNum; k++) {
                infoDataView.Rows[k].Cells["index"].Value = ((SubEquInfo)deviceInfoList[k - 1]).index;
                infoDataView.Rows[k].Cells["updateFlag"].Value = "False";
                infoDataView.Rows[k].Cells["type"].Value = ((SubEquInfo)deviceInfoList[k - 1]).typeStr;

                string firmwareVersion = ((SubEquInfo)deviceInfoList[k - 1]).firmwareVersion;
                if (firmwareVersion.Contains("N0") || firmwareVersion.Contains("n0")) {
                    firmwareVersion = text + firmwareVersion;
                }

                infoDataView.Rows[k].Cells["version"].Value = firmwareVersion;
                infoDataView.Rows[k].Cells["updateRes"].Value = "--";
                infoDataView.Rows[k].Cells["reset"].Value = "R";
                infoDataView.Rows[k].Visible = true;
            }

            if (currentTestedNum > 0) {
                string msg = string.Format("当前状态：级联了 {0} 台设备", currentTestedNum);
                if (LanguageOper.available == true) {
                    msg = string.Format(LanguageOper.ReadValue(section, "msgStr.0"), currentTestedNum);
                }
                stateLabel.Text = msg;
                lastTestedNum = currentTestedNum;
            } else {
                string msg = "当前状态：未检测到设备";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "msgStr.1");
                }
                stateLabel.Text = msg;
                lastTestedNum = 0;
            }

            currentOperLabel.Text = "--";
            setProgressBarValue(0);
        }

        // 【委托实现】更新分控详细信息列表 - 单行信息
        private void refreshRowInfo(int rowIndex, int cellIndex, string value) {
            if (cellIndex == 3 || cellIndex == 4) {
                infoDataView.Rows[rowIndex].Cells[cellIndex].Value = value;
            }
        }

        // 【委托实现】更新整体进度标签
        private void refreshTotalProcessLabel(string value) {
            totalProcessLabel.Text = value;
        }

        // 【委托实现】更新当前操作标签
        private void refreshCurrentOperLabel(string value) {
            currentOperLabel.Text = value;
        }

        // 【委托实现】更新当前升级进度标签
        private void setProgressBarValue(int value) {
            updateProgressBar.Value = value;
            updateStatusLabel.Text = value + " %";
        }

        // 【委托实现】打印日志
        private void typeLog(string str) {
            if (debugSwich) {
                logTextBox.AppendText(str + "\n");
                logTextBox.SelectionStart = logTextBox.TextLength;
                logTextBox.ScrollToCaret();

                logPrintNum++;
                if (logPrintNum > 300) {
                    logTextBox.Text = "";
                    logPrintNum = 0;
                }
            }
        }

        // 读取 .rbf 文件, 填充dataBuffOrign, dataBuff1, dataBuff2
        private bool readRBFFile() {
            // 选择 .rbf 文件
            if (filePathTextBox.Text.Trim().Equals("")) {
                if (rbfFileName.Trim().Equals("")) {
                    string msg = "请选择 .rbf 文件";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.2");
                    }

                    this.Invoke(new Action(() => {
                        MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }));

                    return false;
                }
            }

            // 打开 .rbf 文件并读取内容
            FileStream fs = File.OpenRead(rbfFileName);
            BinaryReader reader = new BinaryReader(fs);

            byte[] orignData = new byte[fs.Length];
            orignData = reader.ReadBytes(orignData.Length);

            // 初始化原始数据 dataBuffOrign 及缓冲区1 dataBuff1
            dataBuffOrign = new byte[256 * 1024];
            dataBuff1 = new byte[256 * 1024];
            for (int i = 0; i <= 0x3FDFF; i++) {
                dataBuff1[i] = 0xFF;
            }
            for (int i = 0x3FE00; i <= 0x3FFFF; i++) {
                dataBuff1[i] = 0x00;
            }

            // 查表进行位转换 bit swap
            for (int i = 0; i < orignData.Length; i++) {
                dataBuff1[i] = Tools.bitSwap(orignData[i]);
                dataBuffOrign[i] = orignData[i];
            }

            // 计算 CRC32
            byte[] bytes4CRC = new byte[0x3FDFF + 1];
            Array.Copy(dataBuff1, bytes4CRC, bytes4CRC.Length);
            int crc32 = Tools.getCRC32(bytes4CRC);
            byte[] crcValue = Tools.int2Byte4BigEnd(crc32);
            dataBuff1[0x3FE00] = crcValue[0];
            dataBuff1[0x3FE01] = crcValue[1];
            dataBuff1[0x3FE02] = crcValue[2];
            dataBuff1[0x3FE03] = crcValue[3];

            // 将 rbf 文件名的前 13 个字节填充到缓冲区 1 的 0x3FF10~0x3FF1C 地址，不足补 0
            string tmpName = rbfSafeFileName.Remove(rbfSafeFileName.LastIndexOf(".rbf"));
            byte[] tmpNameBytes = Tools.String2Bytes(tmpName);
            for (int i = 0x3FF10; i <= 0x3FF1C; i++) {
                dataBuff1[i] = 0x00;
            }
            for (int i = 0; i < 13 && i < tmpNameBytes.Length; i++) {
                dataBuff1[0x3FF10 + i] = tmpNameBytes[i];
            }

            // 初始化缓冲区2 dataBuff2
            dataBuff2 = new byte[256];
            for (int i = 0; i < 256; i++) {
                dataBuff2[i] = 0x00;
            }

            // 将 rbf 文件名的前 13 个字节填充到缓冲区 2 的 0x10~0x1C 地址，不足补 0
            for (int i = 0x10; i <= 0x1C; i++) {
                dataBuff2[i] = 0x00;
            }
            for (int i = 0; i < 13 && i < tmpNameBytes.Length; i++) {
                dataBuff2[0x10 + i] = tmpNameBytes[i];
            }

            return true;
        }

        private bool readBINFile() {
            // 选择 .rbf 文件
            if (filePathTextBox.Text.Trim().Equals("")) {
                if (rbfFileName.Trim().Equals("")) {
                    string msg = "请选择 .bin 文件";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.2");
                    }

                    this.Invoke(new Action(() => {
                        MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }));

                    return false;
                }

                return true;
            }

            // 打开 .bin 文件并读取内容
            FileStream fs = File.OpenRead(rbfFileName);
            BinaryReader reader = new BinaryReader(fs);

            byte[] orignData = new byte[fs.Length];
            orignData = reader.ReadBytes(orignData.Length);

            // 初始化原始数据 dataBuffOrign 及缓冲区1 dataBuff1
            dataBuffOrign = new byte[256 * 1024];
            dataBuff1 = new byte[256 * 1024];

            for (int i = 0; i < orignData.Length; i++) {
                dataBuff1[i] = orignData[i];
                dataBuffOrign[i] = orignData[i];
            }

            // bin文件大小
            int datalen = orignData.Length;
            // 长度设为1k的整数倍
            if (datalen % 1024 != 0) {
                datalen = (datalen / 1024 + 1) * 1024;
            }

            // 计算crc32
            byte[] crcbyte = new byte[datalen];
            Array.Copy(dataBuff1, crcbyte, crcbyte.Length);
            int crc32 = Tools.getCRC32(crcbyte);
            dataBuff2 = new byte[256];
            for (int i = 0; i < 256; i++) {
                dataBuff2[i] = 0x00;
            }
            byte[] crcValue = Tools.int2Byte4SmallEnd(crc32);
            dataBuff2[0x00] = crcValue[0];
            dataBuff2[0x01] = crcValue[1];
            dataBuff2[0x02] = crcValue[2];
            dataBuff2[0x03] = crcValue[3];


            byte[] datalenValue = Tools.int2Byte4SmallEnd(datalen);
            dataBuff2[0x0c] = datalenValue[0];
            dataBuff2[0x0d] = datalenValue[1];
            dataBuff2[0x0e] = datalenValue[2];
            dataBuff2[0x0f] = datalenValue[3];

            // crc起止地址 起始地址为0 结束地址为文件长度对1k向上取整
            dataBuff2[0x04] = 0x00;
            dataBuff2[0x05] = 0x00;
            dataBuff2[0x06] = 0x00;
            dataBuff2[0x07] = 0x00;
            dataBuff2[0x08] = datalenValue[0];
            dataBuff2[0x09] = datalenValue[1];
            dataBuff2[0x0a] = datalenValue[2];
            dataBuff2[0x0b] = datalenValue[3];
            return true;
        }

        // 在线升级操作集 - 线程方法 - 串行流程
        private void updateProcess() {
            bool readSuccess = readRBFFile();

            if (readSuccess) {
                int successNum = 0;

                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    totalProcessLabel.Invoke(refreshTotalProcessLabelDelegate, (k + " / " + updateSubEquDepth.Count));

                    if (forceStopUpdate) {
                        break;
                    }

                    // 升级操作前处理
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);

                    string msg = "升级中...";
                    string msg1 = string.Format("设备 {0} - 发送数据", depth);
                    string msg2 = "强制停止";
                    string msg3 = "升级失败";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.3");
                        msg1 = string.Format(LanguageOper.ReadValue(section, "msgStr.4"), depth);
                        msg2 = LanguageOper.ReadValue(section, "str.1");
                        msg3 = LanguageOper.ReadValue(section, "str.2");
                    }
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg);
                    this.Invoke(updateCurrentOperLabelDelegate, msg1);

                    /******************* 执行串行升级操作 *******************/
                    bool updateResult = updateOneSubEquControl(depth);
                    /*****************************************************/

                    // 升级操作后处理 - 局部
                    if (updateResult == true) {
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                        successNum++;
                    } else if (forceStopUpdate) {
                        this.Invoke(refreshRowInfoDelegate, depth, 4, msg2);
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                    } else {
                        this.Invoke(refreshRowInfoDelegate, depth, 4, msg3);
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                    }
                }

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    string msg = "强制停止";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.1");
                    }
                    this.Invoke(updateCurrentOperLabelDelegate, msg);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(refreshTotalProcessLabelDelegate, (updateSubEquDepth.Count + " / " + updateSubEquDepth.Count));

                    string msg = "全部完成";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.3");
                    }
                    this.Invoke(updateCurrentOperLabelDelegate, msg);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg1 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg1 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => {
                            MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        //在线升级操作集 - 线程方法 - bin升级 - 串行流程
        private void updatebinProcess() {
            bool readSuccess = readBINFile();

            if (readSuccess) {
                int successNum = 0;

                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    totalProcessLabel.Invoke(refreshTotalProcessLabelDelegate, (k + " / " + updateSubEquDepth.Count));

                    if (forceStopUpdate) {
                        break;
                    }

                    // 升级操作前处理
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);

                    string msg = "升级中...";
                    string msg1 = string.Format("设备 {0} - 发送数据", depth);
                    string msg2 = "强制停止";
                    string msg3 = "升级失败";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.3");
                        msg1 = string.Format(LanguageOper.ReadValue(section, "msgStr.4"), depth);
                        msg2 = LanguageOper.ReadValue(section, "str.1");
                        msg3 = LanguageOper.ReadValue(section, "str.2");
                    }
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg);
                    this.Invoke(updateCurrentOperLabelDelegate, msg1);

                    /******************* 执行串行升级操作 *******************/
                    bool updateResult = updateOneSubEquControlMCU(depth);
                    /*****************************************************/

                    // 升级操作后处理 - 局部
                    if (updateResult == true) {
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                        successNum++;
                    } else if (forceStopUpdate) {
                        this.Invoke(refreshRowInfoDelegate, depth, 4, msg2);
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                    } else {
                        this.Invoke(refreshRowInfoDelegate, depth, 4, msg3);
                        this.Invoke(updateCurrentOperLabelDelegate, "--");
                    }
                }

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    string msg = "强制停止";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.1");
                    }
                    this.Invoke(updateCurrentOperLabelDelegate, msg);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(refreshTotalProcessLabelDelegate, (updateSubEquDepth.Count + " / " + updateSubEquDepth.Count));

                    string msg = "全部完成";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.3");
                    }
                    this.Invoke(updateCurrentOperLabelDelegate, msg);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg1 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg1 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => {
                            MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        // 在线升级操作集 - 线程方法 - 并行流程
        private void updateProcess_parallet() {
            bool readSuccess = readRBFFile();

            if (readSuccess) {
                int successNum = 0;

                // 升级操作前处理
                string msg = "并行";
                string msg1 = "升级中...";
                string msg2 = "发送数据";
                string msg3 = "强制停止";
                string msg4 = "全部完成";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "str.4");
                    msg1 = LanguageOper.ReadValue(section, "msgStr.3");
                    msg2 = LanguageOper.ReadValue(section, "str.5");
                    msg3 = LanguageOper.ReadValue(section, "str.1");
                    msg4 = LanguageOper.ReadValue(section, "str.3");
                }

                this.Invoke(refreshTotalProcessLabelDelegate, msg);
                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg1);
                }
                this.Invoke(updateCurrentOperLabelDelegate, msg2);

                /******************* 执行并行升级操作 *******************/
                successNum = updateSubEquControls(updateSubEquDepth);
                /*****************************************************/

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    this.Invoke(updateCurrentOperLabelDelegate, msg3);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(updateCurrentOperLabelDelegate, msg4);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg5 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg5 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => {
                            MessageBoxEx.Show(this, msg5, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        // 在线升级操作集 - 线程方法 - bin升级 - 并行流程
        private void updatebinProcess_parallet() {
            bool readSuccess = readBINFile();

            if (readSuccess) {
                int successNum = 0;

                // 升级操作前处理
                string msg = "并行";
                string msg1 = "升级中...";
                string msg2 = "发送数据";
                string msg3 = "强制停止";
                string msg4 = "全部完成";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "str.4");
                    msg1 = LanguageOper.ReadValue(section, "msgStr.3");
                    msg2 = LanguageOper.ReadValue(section, "str.5");
                    msg3 = LanguageOper.ReadValue(section, "str.1");
                    msg4 = LanguageOper.ReadValue(section, "str.3");
                }

                this.Invoke(refreshTotalProcessLabelDelegate, msg);
                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg1);
                }
                this.Invoke(updateCurrentOperLabelDelegate, msg2);

                /******************* 执行并行升级操作 *******************/
                successNum = updateSubEquControlsMCU(updateSubEquDepth);
                /*****************************************************/

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    this.Invoke(updateCurrentOperLabelDelegate, msg3);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(updateCurrentOperLabelDelegate, msg4);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg5 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg5 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => { 
                            MessageBoxEx.Show(this, msg5, tip, MessageBoxButtons.OK, MessageBoxIcon.Information); 
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        // 在线升级操作集 - 线程方法 - 全局流程
        private void updateProcess_total() {
            bool readSuccess = readRBFFile();

            if (readSuccess) {
                int successNum = 0;

                string msg = "全局";
                string msg1 = "升级中...";
                string msg2 = "发送数据";
                string msg3 = "强制停止";
                string msg4 = "全部完成";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "str.6");
                    msg1 = LanguageOper.ReadValue(section, "msgStr.3");
                    msg2 = LanguageOper.ReadValue(section, "str.5");
                    msg3 = LanguageOper.ReadValue(section, "str.1");
                    msg4 = LanguageOper.ReadValue(section, "str.3");
                }

                // 升级操作前处理
                totalProcessLabel.Invoke(refreshTotalProcessLabelDelegate, msg);
                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg1);
                }
                this.Invoke(updateCurrentOperLabelDelegate, msg2);

                /********************** 执行全局升级操作 **********************/
                successNum = updateAllSubEquControls(updateSubEquDepth);
                /***********************************************************/

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    this.Invoke(updateCurrentOperLabelDelegate, msg3);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(updateCurrentOperLabelDelegate, msg4);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg5 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg5 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => {
                            MessageBoxEx.Show(this, msg5, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        // 在线升级操作集 - 线程方法 - bin升级 - 全局流程
        private void updatebinProcess_total() {
            bool readSuccess = readBINFile();

            if (readSuccess) {
                int successNum = 0;

                string msg = "全局";
                string msg1 = "升级中...";
                string msg2 = "发送数据";
                string msg3 = "强制停止";
                string msg4 = "全部完成";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "str.6");
                    msg1 = LanguageOper.ReadValue(section, "msgStr.3");
                    msg2 = LanguageOper.ReadValue(section, "str.5");
                    msg3 = LanguageOper.ReadValue(section, "str.1");
                    msg4 = LanguageOper.ReadValue(section, "str.3");
                }

                // 升级操作前处理
                totalProcessLabel.Invoke(refreshTotalProcessLabelDelegate, msg);
                for (int k = 0; k < updateSubEquDepth.Count; k++) {
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg1);
                }
                this.Invoke(updateCurrentOperLabelDelegate, msg2);

                /********************** 执行全局升级操作 **********************/
                successNum = updateAllSubEquControlsMCU(updateSubEquDepth);
                /***********************************************************/

                // 升级操作后处理
                this.Invoke(setProgressBarValueDelegate, 100);

                if (forceStopUpdate) {
                    this.Invoke(updateCurrentOperLabelDelegate, msg3);
                    forceStopUpdate = false;
                } else {
                    this.Invoke(updateCurrentOperLabelDelegate, msg4);

                    if (successNum == updateSubEquDepth.Count) {
                        // 复位所有分控 - 倒序
                        this.Invoke(resetSubControlOperDelegate);
                    } else {
                        string msg5 = "部分设备升级失败, 请检查";
                        if (LanguageOper.available == true) {
                            msg5 = LanguageOper.ReadValue(section, "msgStr.5");
                        }
                        this.Invoke(new Action(() => {
                            MessageBoxEx.Show(this, msg5, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        }));
                    }
                }

                // 升级操作后恢复界面按钮
                this.Invoke(enableButtonsAfterUpdateDelegate);
            }
        }

        // 在线升级分控 - 串行
        private bool updateOneSubEquControl(int subEquDepth) {
            string msg = "强制停止";
            string msg1 = "发送数据";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
            }

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            /*********************************** 在线升级 ****************************************/

            refreshRowInfo(subEquDepth, 4, msg1);

            // 将【缓冲区1】内容写入Flash固件区 - 内容长度256KBytes
            if (target == DeviceType.SubControl) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff1, 0x00D80000, 0x00C80000, dataBuff1.Length, true, DeviceType.SubControl);
            } else if (target == DeviceType.Equipment) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff1, 0x00F80000, 0x00E80000, dataBuff1.Length, true, DeviceType.Equipment);
            }

            // 将【缓冲区2】内容写入Flash数据区2 - 内容长度256Bytes
            if (target == DeviceType.SubControl) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.SubControl);
            } else if (target == DeviceType.Equipment) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.Equipment);
            }

            /********************************* End 在线升级 **************************************/

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            /******************************* 检查Flash - 串行 ************************************/

            this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg2);
            this.Invoke(updateCurrentOperLabelDelegate, msg3);

            // 读取Flash, 验证【缓冲区1】写入内容的正确性
            bool ckeckRes1 = false;
            byte[] firmwareData = null;
            if (target == DeviceType.SubControl) {
                firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, subEquDepth, 0x00C80000, 256 * 1024, true, DeviceType.SubControl);
            } else if (target == DeviceType.Equipment) {
                firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, subEquDepth, 0x00E80000, 256 * 1024, true, DeviceType.Equipment);
            }

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            int compareRes1_tmp1 = Tools.MemoryCompare(firmwareData, dataBuff1);
            int compareRes1_tmp2 = Tools.MemoryCompare(firmwareData, dataBuffOrign);
            int compareRes1 = -1;

            // 适应是否进行 bitSwap 两种情况
            if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                compareRes1 = 0;
            }

            if (compareRes1 == 0) {
                ckeckRes1 = true;
            } else {
                //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
            }

            // 读取Flash, 验证【缓冲区2】写入内容的正确性
            bool ckeckRes2 = false;
            byte[] rbfNameData = new byte[256];
            bool timeout = true;
            if (target == DeviceType.SubControl) {
                timeout = baseCoreNet.readSubMem(currentDeviceIndex, subEquDepth, 0x004CFF00, ref rbfNameData);
            } else if (target == DeviceType.Equipment) {
                timeout = baseCoreNet.readEquMem(currentDeviceIndex, subEquDepth, 0x004CFF00, ref rbfNameData);
            }
            int retryTimes = 0;
            while (timeout == true) {
                if (retryTimes > 2) {
                    break;
                } else {
                    if (target == DeviceType.SubControl) {
                        timeout = baseCoreNet.readSubMem(currentDeviceIndex, subEquDepth, 0x004CFF00, ref rbfNameData);
                    } else if (target == DeviceType.Equipment) {
                        timeout = baseCoreNet.readEquMem(currentDeviceIndex, subEquDepth, 0x004CFF00, ref rbfNameData);
                    }
                    retryTimes++;
                }
            }

            int compareRes2 = Tools.MemoryCompare(rbfNameData, dataBuff2);
            this.Invoke(typeLogDelegate, "rbfNameData = \n" + Tools.Byte2HexString(rbfNameData) + "compareRes2 = " + compareRes2);
            if (compareRes2 == 0) {
                ckeckRes2 = true;
            }
            if (forceStopUpdate == true) {
                ckeckRes2 = false;
            }

            // 处理检查结果
            if (ckeckRes1 == false || ckeckRes2 == false) {
                string text = string.Format("Flash检查失败, 固件区: {0}, 数据区2: {1}", ckeckRes1, ckeckRes2);
                if (LanguageOper.available == true) {
                    text = string.Format(LanguageOper.ReadValue(section, "msgStr.7"), ckeckRes1, ckeckRes2);
                }
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, text);
                return false;
            } else {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg4);
                return true;
            }

            /***************************** End 检查Flash - 串行 **********************************/
        }

        // 在线升级分控MCU - 串行
        private bool updateOneSubEquControlMCU(int subEquDepth) {
            string msg = "强制停止";
            string msg1 = "发送数据";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
            }

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            /*********************************** 在线升级 ****************************************/
            refreshRowInfo(subEquDepth, 4, msg1);

            // 切换mcu模式
            byte[] mcumode = new byte[1];
            if (p_type == ProgramType.App) {
                mcumode[0] = 0x01;
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                Thread.Sleep(mcuModeSwitchInterval);
            } else if (p_type == ProgramType.Boot) {
                // mcu 启动程序 不需要切换mcu模式
            }

            int datalen = (dataBuff2[0x0c] << 24) | (dataBuff2[0x0d] << 16) | (dataBuff2[0x0e]) << 8 | (dataBuff2[0x0f]);

            // 擦除需要升级的区域
            byte[] cleanbuff = new byte[8];
            for (int i = 0; i < 8; i++) {
                cleanbuff[i] = 0;
            }
            cleanbuff[4] = dataBuff2[0x0c];
            cleanbuff[5] = dataBuff2[0x0d];
            cleanbuff[6] = dataBuff2[0x0e];
            cleanbuff[7] = dataBuff2[0x0f];
            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, cleanbuff, 0x20301100, 0x20001100, cleanbuff.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, cleanbuff, 0x20301100, 0x20002100, cleanbuff.Length, true, DeviceType.SubControl);
            }

            Thread.Sleep(3000);

            // 将【缓冲区1】内容写入 - 内容长度

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff1, 0x20300000, 0x20100000, datalen, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, dataBuff1, 0x20300000, 0x20400000, datalen, true, DeviceType.SubControl);
            }

            // 将CRC校验地址写入
            byte[] crcAddr = new byte[8];
            for (int i = 0; i < 8; i++) {
                crcAddr[i] = 0;
            }
            crcAddr[0] = dataBuff2[0x04];
            crcAddr[1] = dataBuff2[0x05];
            crcAddr[2] = dataBuff2[0x06];
            crcAddr[3] = dataBuff2[0x07];
            crcAddr[4] = dataBuff2[0x08];
            crcAddr[5] = dataBuff2[0x09];
            crcAddr[6] = dataBuff2[0x0a];
            crcAddr[7] = dataBuff2[0x0b];

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, crcAddr, 0x20301200, 0x20001200, crcAddr.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, crcAddr, 0x20301200, 0x20002200, crcAddr.Length, true, DeviceType.SubControl);
            }
            Thread.Sleep(1000);


            /********************************* End 在线升级 **************************************/

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            /******************************* 检查Flash - 串行 ************************************/

            this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg2);
            this.Invoke(updateCurrentOperLabelDelegate, msg3);

            // 读取Flash, 验证【缓冲区1】写入内容的正确性
            bool ckeckRes1 = false;
            byte[] firmwareData = null;

            if (p_type == ProgramType.App) {
                firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, subEquDepth, 0x20001300, 256, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, subEquDepth, 0x20002300, 256, true, DeviceType.SubControl);
            }

            if (forceStopUpdate) {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg);
                return false;
            }

            int compareRes1_tmp1 = 0;
            int compareRes1_tmp2 = 0;
            int compareRes1 = -1;

            // 适应是否进行 bitSwap 两种情况
            if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                compareRes1 = 0;
            }

            if (compareRes1 == 0) {
                ckeckRes1 = true;
            } else {
                //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
            }

            // 比较软件与mcu计算的crc是否存在差异
            var crcByPC = new byte[4];
            Array.Copy(dataBuff2, 0, crcByPC, 0, 4);
            var crcByMcu = new byte[4];
            Array.Copy(firmwareData, 0, crcByMcu, 0, 4);
            if (!crcByPC.SequenceEqual(crcByMcu)) {
                //ckeckRes1 = false;
            }

            // 将CRC校验和写入
            byte[] crcValue = new byte[12];
            Array.Copy(firmwareData, 0, crcValue, 0, 4);
            Array.Copy(dataBuff2, 4, crcValue, 4, 8);

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, crcValue, 0x20301400, 0x20001400, crcValue.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, crcValue, 0x20301400, 0x20002400, crcValue.Length, true, DeviceType.SubControl);
            }

            Thread.Sleep(100);

            if (ckeckRes1) {
                if (p_type == ProgramType.App) {
                    // 跳转至功能程序
                    mcumode[0] = 0x02;
                    baseCoreNet.write2Flash(currentDeviceIndex, subEquDepth, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                } else if (p_type == ProgramType.Boot) {
                    // mcu 启动程序 不需要跳转至功能程序
                }
            }

            // 处理检查结果
            if (ckeckRes1 == false) {
                string text = string.Format("Flash检查失败");
                if (LanguageOper.available == true) {
                    text = string.Format(LanguageOper.ReadValue(section, "msgStr.7"), ckeckRes1);
                }
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, text);
                return false;
            } else {
                this.Invoke(refreshRowInfoDelegate, subEquDepth, 4, msg4);
                return true;
            }

            /***************************** End 检查Flash - 串行 **********************************/
        }

        // 在线升级分控 - 并行
        private int updateSubEquControls(ArrayList updateDepthList) {
            string msg = "强制停止";
            string msg1 = "发送数据";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            string msg5 = "待检查";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
                msg5 = LanguageOper.ReadValue(section, "str.8");
            }

            /*********************************** 在线升级 ****************************************/

            int successNum = 0;

            int[] depthList = new int[updateDepthList.Count];
            for (int k = 0; k < depthList.Length; k++) {
                depthList[k] = Convert.ToInt32(updateSubEquDepth[k]);
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg1);
            }

            int writeAddr, eraseAddr;

            if (p_type == ProgramType.Boot) {
                writeAddr = 0x00000000;
            } else if (p_type == ProgramType.Test) {
                writeAddr = 0x00040000;
            } else //if (p_type == ProgramType.App)
            {
                writeAddr = 0x00080000;
            }
            eraseAddr = writeAddr + 0x00100000;

            // 将【缓冲区1】内容写入Flash固件区 - 内容长度256KBytes
            // 将【缓冲区2】内容写入Flash数据区2 - 内容长度256Bytes，App模式
            if (target == DeviceType.Equipment) {
                writeAddr = writeAddr + 0x00E00000;
                eraseAddr = eraseAddr + 0x00E00000;
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff1, eraseAddr, writeAddr, dataBuff1.Length, true, DeviceType.Equipment);
                if (p_type == ProgramType.App) {
                    baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.Equipment);
                }
            } else //if (target == DeviceType.SubControl)
            {
                writeAddr = writeAddr + 0x00C00000;
                eraseAddr = eraseAddr + 0x00C00000;
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff1, eraseAddr, writeAddr, dataBuff1.Length, true, DeviceType.SubControl);
                if (p_type == ProgramType.App) {
                    baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.SubControl);
                }
            }

            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg5);
            }

            /********************************* End 在线升级 **************************************/

            /******************************* 检查Flash - 串行 ************************************/

            for (int k = 0; k < depthList.Length; k++) {
                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }

                int depth = depthList[k];
                this.Invoke(refreshRowInfoDelegate, depth, 4, msg2);
                this.Invoke(updateCurrentOperLabelDelegate, msg3);

                // 读取Flash, 验证【缓冲区1】写入内容的正确性
                bool ckeckRes1 = false;
                byte[] firmwareData = null;
                if (target == DeviceType.SubControl) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, depth, (uint)writeAddr, 256 * 1024, true, DeviceType.SubControl);
                } else if (target == DeviceType.Equipment) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, depth, (uint)writeAddr, 256 * 1024, true, DeviceType.Equipment);
                }

                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }

                int compareRes1_tmp1 = Tools.MemoryCompare(firmwareData, dataBuff1);
                int compareRes1_tmp2 = Tools.MemoryCompare(firmwareData, dataBuffOrign);
                int compareRes1 = -1;

                // 适应是否进行 bitSwap 两种情况
                if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                    compareRes1 = 0;
                }

                if (compareRes1 == 0) {
                    ckeckRes1 = true;
                } else {
                    //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
                }

                // 读取Flash, 验证【缓冲区2】写入内容的正确性
                bool ckeckRes2 = true;
                if (p_type == ProgramType.App) {
                    byte[] rbfNameData = new byte[256];
                    bool timeout = true;
                    ckeckRes2 = false;

                    if (target == DeviceType.SubControl) {
                        timeout = baseCoreNet.readSubMem(currentDeviceIndex, depth, 0x004CFF00, ref rbfNameData);
                    } else if (target == DeviceType.Equipment) {
                        timeout = baseCoreNet.readEquMem(currentDeviceIndex, depth, 0x004CFF00, ref rbfNameData);
                    }
                    int retryTimes = 0;
                    while (timeout == true) {
                        if (retryTimes > 2) {
                            break;
                        } else {
                            if (target == DeviceType.SubControl) {
                                timeout = baseCoreNet.readSubMem(currentDeviceIndex, depth, 0x004CFF00, ref rbfNameData);
                            } else if (target == DeviceType.Equipment) {
                                timeout = baseCoreNet.readEquMem(currentDeviceIndex, depth, 0x004CFF00, ref rbfNameData);
                            }
                            retryTimes++;
                        }
                    }

                    if (forceStopUpdate) {
                        this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                        continue;
                    }

                    int compareRes2 = Tools.MemoryCompare(rbfNameData, dataBuff2);
                    this.Invoke(typeLogDelegate, "rbfNameData = \n" + Tools.Byte2HexString(rbfNameData) + "compareRes2 = " + compareRes2);
                    if (timeout == false && compareRes2 == 0) {
                        ckeckRes2 = true;
                    }
                    if (forceStopUpdate == true) {
                        ckeckRes2 = false;
                    }
                }

                // 处理检查结果
                if (ckeckRes1 == false || ckeckRes2 == false) {
                    string text = string.Format("Flash检查失败, 固件区: {0}, 数据区2: {1}", ckeckRes1, ckeckRes2);
                    if (LanguageOper.available == true) {
                        text = string.Format(LanguageOper.ReadValue(section, "msgStr.7"), ckeckRes1, ckeckRes2);
                    }
                    this.Invoke(refreshRowInfoDelegate, depth, 4, text);
                } else {
                    successNum++;
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg4);
                }

                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }
            }

            /***************************** End 检查Flash - 串行 **********************************/

            return successNum;
        }

        // 在线升级分控MCU - 并行
        private int updateSubEquControlsMCU(ArrayList updateDepthList) {
            string msg = "强制停止";
            string msg1 = "发送数据";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            string msg5 = "待检查";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
                msg5 = LanguageOper.ReadValue(section, "str.8");
            }

            /*********************************** 在线升级 ****************************************/

            int successNum = 0;

            int[] depthList = new int[updateDepthList.Count];
            for (int k = 0; k < depthList.Length; k++) {
                depthList[k] = Convert.ToInt32(updateSubEquDepth[k]);
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg1);
            }

            // 切换mcu模式
            byte[] mcumode = new byte[1];
            if (p_type == ProgramType.App) {
                mcumode[0] = 0x01;
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                Thread.Sleep(mcuModeSwitchInterval);
            } else if (p_type == ProgramType.Boot) {
                // mcu 启动程序 不需要切换mcu模式
            }

            int datalen = (dataBuff2[0x0c] << 24) | (dataBuff2[0x0d] << 16) | (dataBuff2[0x0e]) << 8 | (dataBuff2[0x0f]);

            // 擦除需要升级的区域
            byte[] cleanbuff = new byte[8];
            for (int i = 0; i < 8; i++) {
                cleanbuff[i] = 0;
            }
            cleanbuff[4] = dataBuff2[0x0c];
            cleanbuff[5] = dataBuff2[0x0d];
            cleanbuff[6] = dataBuff2[0x0e];
            cleanbuff[7] = dataBuff2[0x0f];

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, cleanbuff, 0x20301100, 0x20001100, cleanbuff.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, cleanbuff, 0x20301100, 0x20002100, cleanbuff.Length, true, DeviceType.SubControl);
            }
            Thread.Sleep(3000);

            // 将【缓冲区1】内容写入 - 内容长度
            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff1, 0x20300000, 0x20100000, datalen, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, dataBuff1, 0x20300000, 0x20400000, datalen, true, DeviceType.SubControl);
            }
            // 将CRC校验地址写入
            byte[] crcAddr = new byte[8];
            for (int i = 0; i < 8; i++) {
                crcAddr[i] = 0;
            }
            crcAddr[0] = dataBuff2[0x04];
            crcAddr[1] = dataBuff2[0x05];
            crcAddr[2] = dataBuff2[0x06];
            crcAddr[3] = dataBuff2[0x07];
            crcAddr[4] = dataBuff2[0x08];
            crcAddr[5] = dataBuff2[0x09];
            crcAddr[6] = dataBuff2[0x0a];
            crcAddr[7] = dataBuff2[0x0b];

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, crcAddr, 0x20301200, 0x20001200, crcAddr.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_parallet(currentDeviceIndex, depthList, crcAddr, 0x20301200, 0x20002200, crcAddr.Length, true, DeviceType.SubControl);
            }
            Thread.Sleep(1000);

            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg5);
            }

            /********************************* End 在线升级 **************************************/

            /******************************* 检查Flash - 串行 ************************************/

            for (int k = 0; k < depthList.Length; k++) {
                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }

                int depth = depthList[k];
                bool ckeckRes1 = false;
                byte[] firmwareData = null;

                if (p_type == ProgramType.App) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, depth, 0x20001300, 256, true, DeviceType.SubControl);
                } else if (p_type == ProgramType.Boot) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, depth, 0x20002300, 256, true, DeviceType.SubControl);
                }

                int compareRes1_tmp1 = 0;
                int compareRes1_tmp2 = 0;
                int compareRes1 = -1;

                // 适应是否进行 bitSwap 两种情况
                if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                    compareRes1 = 0;
                }

                if (compareRes1 == 0) {
                    ckeckRes1 = true;
                } else {
                    //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
                }

                // 比较软件与mcu计算的crc是否存在差异
                var crcByPC = new byte[4];
                Array.Copy(dataBuff2, 0, crcByPC, 0, 4);
                var crcByMcu = new byte[4];
                Array.Copy(firmwareData, 0, crcByMcu, 0, 4);
                if (!crcByPC.SequenceEqual(crcByMcu)) {
                    //ckeckRes1 = false;
                }

                // 将CRC校验和写入
                byte[] crcValue = new byte[12];
                Array.Copy(firmwareData, 0, crcValue, 0, 4);
                Array.Copy(dataBuff2, 4, crcValue, 4, 8);

                if (p_type == ProgramType.App) {
                    baseCoreNet.write2Flash(currentDeviceIndex, depth, crcValue, 0x20301400, 0x20001400, crcValue.Length, true, DeviceType.SubControl);
                } else if (p_type == ProgramType.Boot) {
                    baseCoreNet.write2Flash(currentDeviceIndex, depth, crcValue, 0x20301400, 0x20002400, crcValue.Length, true, DeviceType.SubControl);
                }

                Thread.Sleep(100);

                if (ckeckRes1) {
                    if (p_type == ProgramType.App) {
                        // 跳转至功能程序
                        mcumode[0] = 0x02;
                        baseCoreNet.write2Flash(currentDeviceIndex, depth, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                    } else if (p_type == ProgramType.Boot) {
                        // mcu 启动程序 不需要跳转至功能程序
                    }
                }

                Thread.Sleep(100);

                // 处理检查结果
                if (ckeckRes1 == false) {
                    string text = string.Format("Flash检查失败");
                    if (LanguageOper.available == true) {
                        text = string.Format(LanguageOper.ReadValue(section, "msgStr.26"));
                    }
                    this.Invoke(refreshRowInfoDelegate, depth, 4, text);
                } else {
                    successNum++;
                    this.Invoke(refreshRowInfoDelegate, depth, 4, msg4);
                }

                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }

            }

            /***************************** End 检查Flash - 串行 **********************************/

            return successNum;
        }

        // 在线升级分控 - 全局
        private int updateAllSubEquControls(ArrayList updateDepthList) {
            string msg = "强制停止";
            string msg1 = "发送数据...";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            string msg5 = "待检查";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
                msg5 = LanguageOper.ReadValue(section, "str.8");
            }

            /*********************************** 在线升级 ****************************************/

            int successNum = 0;

            int[] depthList = new int[updateDepthList.Count];
            for (int k = 0; k < depthList.Length; k++) {
                depthList[k] = Convert.ToInt32(updateSubEquDepth[k]);
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg1);
            }

            // 将【缓冲区1】内容写入Flash固件区 - 内容长度256KBytes - 向全局发送数据
            if (target == DeviceType.SubControl) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff1, 0x00D80000, 0x00C80000, dataBuff1.Length, true, DeviceType.SubControl);
            } else if (target == DeviceType.Equipment) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff1, 0x00F80000, 0x00E80000, dataBuff1.Length, true, DeviceType.Equipment);
            }

            // 将【缓冲区2】内容写入Flash数据区2  - 内容长度256Bytes - 向全局发送数据
            if (target == DeviceType.SubControl) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.SubControl);
            } else if (target == DeviceType.Equipment) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff2, 0x005CFF00, 0x004CFF00, dataBuff2.Length, false, DeviceType.Equipment);
            }

            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg5);
            }

            /********************************* End 在线升级 **************************************/

            /******************************* 检查Flash - 全局 ************************************/

            // 全局设置
            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg2);
            }
            this.Invoke(updateCurrentOperLabelDelegate, msg3);

            // 检查Flash - 仅检查级联深度为 1 的分控卡
            for (int k = 0; k < 1; k++) {
                int checkDepth = depthList[k];

                // 仅读取级联深度为 1 的分控卡 Flash, 验证【缓冲区1】写入内容的正确性
                bool ckeckRes1 = false;
                byte[] firmwareData = null;
                if (target == DeviceType.SubControl) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, checkDepth, 0x00C80000, 256 * 1024, true, DeviceType.SubControl);
                } else if (target == DeviceType.Equipment) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, checkDepth, 0x00E80000, 256 * 1024, true, DeviceType.Equipment);
                }

                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                    continue;
                }

                int compareRes1_tmp1 = Tools.MemoryCompare(firmwareData, dataBuff1);
                int compareRes1_tmp2 = Tools.MemoryCompare(firmwareData, dataBuffOrign);
                int compareRes1 = -1;

                // 适应是否进行 bitSwap 两种情况
                if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                    compareRes1 = 0;
                }

                if (compareRes1 == 0) {
                    ckeckRes1 = true;
                } else {
                    //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
                }

                // 仅读取级联深度为 1 的分控卡Flash, 验证【缓冲区2】写入内容的正确性
                bool ckeckRes2 = false;
                byte[] rbfNameData = new byte[256];
                bool timeout = true;
                if (target == DeviceType.SubControl) {
                    timeout = baseCoreNet.readSubMem(currentDeviceIndex, checkDepth, 0x004CFF00, ref rbfNameData);
                } else if (target == DeviceType.Equipment) {
                    timeout = baseCoreNet.readEquMem(currentDeviceIndex, checkDepth, 0x004CFF00, ref rbfNameData);
                }
                int retryTimes = 0;
                while (timeout == true) {
                    if (retryTimes > 2) {
                        break;
                    } else {
                        if (target == DeviceType.SubControl) {
                            timeout = baseCoreNet.readSubMem(currentDeviceIndex, checkDepth, 0x004CFF00, ref rbfNameData);
                        } else if (target == DeviceType.Equipment) {
                            timeout = baseCoreNet.readEquMem(currentDeviceIndex, checkDepth, 0x004CFF00, ref rbfNameData);
                        }
                        retryTimes++;
                    }
                }

                int compareRes2 = Tools.MemoryCompare(rbfNameData, dataBuff2);
                this.Invoke(typeLogDelegate, "rbfNameData = \n" + Tools.Byte2HexString(rbfNameData) + "compareRes2 = " + compareRes2);
                if (compareRes2 == 0) {
                    ckeckRes2 = true;
                }
                if (forceStopUpdate == true) {
                    ckeckRes2 = false;
                }

                // 处理检查结果
                if (ckeckRes1 == false || ckeckRes2 == false) {
                    string text = string.Format("Flash检查失败, 固件区: {0}, 数据区2: {1}", ckeckRes1, ckeckRes2);
                    if (LanguageOper.available == true) {
                        text = string.Format(LanguageOper.ReadValue(section, "msgStr.7"), ckeckRes1, ckeckRes2);
                    }

                    // 全局设置
                    for (int kk = 0; kk < depthList.Length; kk++) {
                        this.Invoke(refreshRowInfoDelegate, depthList[kk], 4, text);
                    }
                } else {
                    // 全局设置
                    successNum = updateDepthList.Count;
                    for (int kk = 0; kk < depthList.Length; kk++) {
                        this.Invoke(refreshRowInfoDelegate, depthList[kk], 4, msg4);
                    }
                }
            }

            for (int k = 0; k < depthList.Length; k++) {
                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                }
            }

            /***************************** End 检查Flash - 全局 **********************************/

            return successNum;
        }

        // 在线升级分控MCU - 全局
        private int updateAllSubEquControlsMCU(ArrayList updateDepthList) {
            string msg = "强制停止";
            string msg1 = "发送数据...";
            string msg2 = "数据发送完成, Flash检查中...";
            string msg3 = "检查Flash";
            string msg4 = "升级完成";
            string msg5 = "待检查";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "str.5");
                msg2 = LanguageOper.ReadValue(section, "msgStr.6");
                msg3 = LanguageOper.ReadValue(section, "str.7");
                msg4 = LanguageOper.ReadValue(section, "msgStr.8");
                msg5 = LanguageOper.ReadValue(section, "str.8");
            }

            /*********************************** 在线升级 ****************************************/

            int successNum = 0;

            int[] depthList = new int[updateDepthList.Count];
            for (int k = 0; k < depthList.Length; k++) {
                depthList[k] = Convert.ToInt32(updateSubEquDepth[k]);
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg1);
            }

            // 切换mcu模式
            byte[] mcumode = new byte[1];
            if (p_type == ProgramType.App) {
                mcumode[0] = 0x01;
                baseCoreNet.write2Flash_total(currentDeviceIndex, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                Thread.Sleep(mcuModeSwitchInterval);
            } else if (p_type == ProgramType.Boot) {
                // mcu 启动程序 不需要切换mcu模式
            }

            int datalen = (dataBuff2[0x0c] << 24) | (dataBuff2[0x0d] << 16) | (dataBuff2[0x0e]) << 8 | (dataBuff2[0x0f]);

            // 擦除需要升级的区域
            byte[] cleanbuff = new byte[8];
            for (int i = 0; i < 8; i++) {
                cleanbuff[i] = 0;
            }
            cleanbuff[4] = dataBuff2[0x0c];
            cleanbuff[5] = dataBuff2[0x0d];
            cleanbuff[6] = dataBuff2[0x0e];
            cleanbuff[7] = dataBuff2[0x0f];
            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, cleanbuff, 0x20301100, 0x20001100, cleanbuff.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, cleanbuff, 0x20301100, 0x20002100, cleanbuff.Length, true, DeviceType.SubControl);
            }
            Thread.Sleep(3000);

            // 将【缓冲区1】内容写入 - 内容长度

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff1, 0x20300000, 0x20100000, datalen, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, dataBuff1, 0x20300000, 0x20400000, datalen, true, DeviceType.SubControl);
            }

            // 将CRC校验地址写入
            byte[] crcAddr = new byte[8];
            for (int i = 0; i < 8; i++) {
                crcAddr[i] = 0;
            }
            crcAddr[0] = dataBuff2[0x04];
            crcAddr[1] = dataBuff2[0x05];
            crcAddr[2] = dataBuff2[0x06];
            crcAddr[3] = dataBuff2[0x07];
            crcAddr[4] = dataBuff2[0x08];
            crcAddr[5] = dataBuff2[0x09];
            crcAddr[6] = dataBuff2[0x0a];
            crcAddr[7] = dataBuff2[0x0b];

            if (p_type == ProgramType.App) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, crcAddr, 0x20301200, 0x20001200, crcAddr.Length, true, DeviceType.SubControl);
            } else if (p_type == ProgramType.Boot) {
                baseCoreNet.write2Flash_total(currentDeviceIndex, crcAddr, 0x20301200, 0x20002200, crcAddr.Length, true, DeviceType.SubControl);
            }
            Thread.Sleep(1000);

            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg5);
            }

            /********************************* End 在线升级 **************************************/

            /******************************* 检查Flash - 全局 ************************************/

            // 全局设置
            for (int k = 0; k < depthList.Length; k++) {
                this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg2);
            }
            this.Invoke(updateCurrentOperLabelDelegate, msg3);

            // 检查Flash - 仅检查级联深度为 1 的分控卡
            for (int k = 0; k < 1; k++) {
                int checkDepth = depthList[k];

                // 仅读取级联深度为 1 的分控卡 Flash, 验证【缓冲区1】写入内容的正确性
                bool ckeckRes1 = false;
                byte[] firmwareData = null;

                if (p_type == ProgramType.App) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, checkDepth, 0x20001300, 256, true, DeviceType.SubControl);
                } else if (p_type == ProgramType.Boot) {
                    firmwareData = baseCoreNet.readFirmware(currentDeviceIndex, checkDepth, 0x20002300, 256, true, DeviceType.SubControl);
                }

                int compareRes1_tmp1 = 0;
                int compareRes1_tmp2 = 0;
                int compareRes1 = -1;

                // 适应是否进行 bitSwap 两种情况
                if (compareRes1_tmp1 == 0 || compareRes1_tmp2 == 0) {
                    compareRes1 = 0;
                }

                if (compareRes1 == 0) {
                    ckeckRes1 = true;
                } else {
                    //this.Invoke(typeLogDelegate, Tools.Byte2HexString4RBF(firmwareData));
                }

                // 比较软件与mcu计算的crc是否存在差异
                var crcByPC = new byte[4];
                Array.Copy(dataBuff2, 0, crcByPC, 0, 4);
                var crcByMcu = new byte[4];
                Array.Copy(firmwareData, 0, crcByMcu, 0, 4);
                if (!crcByPC.SequenceEqual(crcByMcu)) {
                    //ckeckRes1 = false;
                }

                // 将CRC校验和写入
                byte[] crcValue = new byte[12];
                Array.Copy(firmwareData, 0, crcValue, 0, 4);
                Array.Copy(dataBuff2, 4, crcValue, 4, 8);

                if (p_type == ProgramType.App) {
                    baseCoreNet.write2Flash_total(currentDeviceIndex, crcValue, 0x20301400, 0x20001400, crcValue.Length, true, DeviceType.SubControl);
                } else if (p_type == ProgramType.Boot) {
                    baseCoreNet.write2Flash_total(currentDeviceIndex, crcValue, 0x20301400, 0x20002400, crcValue.Length, true, DeviceType.SubControl);
                }

                Thread.Sleep(100);

                if (ckeckRes1) {
                    if (p_type == ProgramType.App) {
                        // 跳转至功能程序
                        mcumode[0] = 0x02;
                        baseCoreNet.write2Flash_total(currentDeviceIndex, mcumode, 0x20301000, 0x20001000, mcumode.Length, true, DeviceType.SubControl);
                    } else if (p_type == ProgramType.Boot) {
                        // mcu 启动程序 不需要跳转至功能程序
                    }
                }

                // 处理检查结果
                if (ckeckRes1 == false) {
                    string text = string.Format("Flash检查失败");
                    if (LanguageOper.available == true) {
                        text = string.Format(LanguageOper.ReadValue(section, "msgStr.7"), ckeckRes1);
                    }
                    // 全局设置
                    for (int kk = 0; kk < depthList.Length; kk++) {
                        this.Invoke(refreshRowInfoDelegate, depthList[kk], 4, text);
                    }
                } else {
                    // 全局设置
                    successNum = updateDepthList.Count;
                    for (int kk = 0; kk < depthList.Length; kk++) {
                        this.Invoke(refreshRowInfoDelegate, depthList[kk], 4, msg4);
                    }
                }
            }

            for (int k = 0; k < depthList.Length; k++) {
                if (forceStopUpdate) {
                    this.Invoke(refreshRowInfoDelegate, depthList[k], 4, msg);
                }
            }

            /***************************** End 检查Flash - 全局 **********************************/

            return successNum;
        }

        // 复位所有分控 - 倒序
        private void resetAllSubEquControllers() {
            string msg = "升级完成, 是否复位全部设备";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "msgStr.9");
            }

            DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (dr == DialogResult.Yes) {
                string text = "已复位";
                if (LanguageOper.available == true) {
                    text = LanguageOper.ReadValue(section, "str.9");
                }

                // 复位所有分控 - 倒序
                for (int k = updateSubEquDepth.Count - 1; k >= 0; k--) {
                    int depth = Convert.ToInt32(updateSubEquDepth[k]);
                    resetSubEquController(depth, false);

                    SubEquInfo info = (SubEquInfo)deviceInfoList[depth - 1];
                    info.firmwareVersion = text;
                    this.Invoke(refreshRowInfoDelegate, depth, 3, text);
                }
            }
        }

        // 复位控制器, 使新固件生效
        private void resetSubEquController(int depth, bool withTip) {
            byte[] dataBuff3 = new byte[256];
            for (int i = 0; i < 256; i++) {
                dataBuff3[i] = 0x0;
            }

            if (target == DeviceType.SubControl) {
                baseCoreNet.writeSubMem(currentDeviceIndex, depth, 0x10000000, dataBuff3, false);
            } else if (target == DeviceType.Equipment) {
                baseCoreNet.writeEquMem(currentDeviceIndex, depth, 0x10000000, dataBuff3, false);
            }

            if (withTip) {
                string msg = "已复位";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "str.9");
                }

                SubEquInfo info = (SubEquInfo)deviceInfoList[depth - 1];
                info.firmwareVersion = msg;
                this.Invoke(refreshRowInfoDelegate, depth, 3, msg);
            }
        }

        // 在线升级 - 进度更新事件处理
        private void writeFlashStateUpdated(object source, WriteEventArgs e) {
            try {
                if (this != null && this.Visible == true) {
                    this.Invoke(setProgressBarValueDelegate, e.processValue);
                }
            } catch {
            }
        }

        // 检查Flash - 进度更新事件处理
        private void readFlashStateUpdated(object source, ReadEventArgs e) {
            try {
                if (this != null && this.Visible == true) {
                    this.Invoke(setProgressBarValueDelegate, e.processValue);
                }
            } catch {
            }
        }

        // 强制进入底层 - 线程方法
        private void forceInitial() {
            int targetIndex = 1;
            int tryNum = 0;
            while (true) {
                if (cancelForceInitial == true) {
                    break;
                }

                if (targetIndex > currentTestedNum) {
                    break;
                }

                string appType = baseCoreNet.getSubControlAppType(currentDeviceIndex, targetIndex);
                Console.Out.WriteLine("appType = " + appType);

                // 当前分控未运行在底层程序
                if (!appType.ToUpper().Equals("N")) {
                    // 对当前分控执行复位操作
                    resetSubEquController(targetIndex, false);

                    // 等待 15 s
                    for (int i = 0; i < 5 * 2; i++) {
                        if (cancelForceInitial == true) {
                            break;
                        }

                        Thread.Sleep(500);

                        if (i % 2 == 0) {
                            Console.Out.WriteLine("sleep " + (i / 2 + 1) + " s");
                            if (tryNum == 0) {
                                string msg = string.Format("强制进入底层, 等待中：{0} s", (i / 2 + 1));
                                if (LanguageOper.available == true) {
                                    msg = string.Format(LanguageOper.ReadValue(section, "msgStr.10"), (i / 2 + 1));
                                }

                                this.Invoke(refreshRowInfoDelegate, targetIndex, 4, msg);
                            } else {
                                string msg = string.Format("重试 {0} - 强制进入底层, 等待中：{1} s", tryNum, (i / 2 + 1));
                                if (LanguageOper.available == true) {
                                    msg = string.Format(LanguageOper.ReadValue(section, "msgStr.11"), tryNum, (i / 2 + 1));
                                }

                                this.Invoke(refreshRowInfoDelegate, targetIndex, 4, msg);
                            }
                        }
                    }
                    if (cancelForceInitial == true) {
                        break;
                    }

                    tryNum++;
                    if (tryNum > 2) {
                        string msg = "强制进入底层失败";
                        if (LanguageOper.available == true) {
                            msg = LanguageOper.ReadValue(section, "msgStr.12");
                        }
                        this.Invoke(refreshRowInfoDelegate, targetIndex, 4, msg);
                        targetIndex++;
                        tryNum = 0;
                    } else {
                        continue;
                    }
                }
                    // 当前分控已运行在底层程序
                else {
                    if (cancelForceInitial == true) {
                        break;
                    }

                    string version = baseCoreNet.getSubControlVersion(currentDeviceIndex, targetIndex);
                    Console.Out.WriteLine("version = " + version);
                    string msg = "底层：";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.0");
                    }
                    this.Invoke(refreshRowInfoDelegate, targetIndex, 3, msg + version);
                    this.Invoke(refreshRowInfoDelegate, targetIndex, 4, "--");

                    targetIndex++;
                    tryNum = 0;
                }
            }

            // 正常结束强制进入底层过程
            if (cancelForceInitial == false) {
            }
                // 手动取消强制进入底层过程
            else {
                string appType = baseCoreNet.getSubControlAppType(currentDeviceIndex, targetIndex);
                string version = baseCoreNet.getSubControlVersion(currentDeviceIndex, targetIndex);

                if (!appType.ToUpper().Equals("N")) {
                    this.Invoke(refreshRowInfoDelegate, targetIndex, 3, version);
                } else {
                    string msg = "底层：";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "str.0");
                    }
                    this.Invoke(refreshRowInfoDelegate, targetIndex, 3, msg + version);
                }
            }

            this.Invoke(refreshRowInfoDelegate, targetIndex, 4, "--");

            // 正常结束强制进入底层过程
            if (cancelForceInitial == false) {
                forceInitialButton_Click(null, null);
            }
        }

        private void showTestEnable(bool enable) {
            pnlProgram.Visible = enable;
            pnlTarget.Visible = enable;
            pnlType.Visible = enable;
            debugCheckBox.Visible = enable;
            clearLogButton.Visible = enable;
            lblProDetails.Visible = !enable;
        }

        #endregion

        #region 界面控件响应

        // 更改目标分区
        private void appRadioButton_CheckedChanged(object sender, EventArgs e) {
            if (appRadioButton.Checked == true) {
                p_type = ProgramType.App;
            } else if (testRadioButton.Checked == true) {
                p_type = ProgramType.Test;
            } else {
                p_type = ProgramType.Boot;
            }

            if (initDone == true) {
                refreshSubInfoButton.PerformClick();
            }
        }

        // 更改升级目标
        private void subRadioButton_CheckedChanged(object sender, EventArgs e) {
            if (subRadioButton.Checked == true) {
                target = DeviceType.SubControl;
            } else {
                target = DeviceType.Equipment;
            }

            if (initDone == true) {
                refreshSubInfoButton.PerformClick();
            }
        }

        // 清空日志
        private void clearLogButton_Click(object sender, EventArgs e) {
            logTextBox.Text = "";
        }

        // 选择 rbf 文件
        private void openButton_Click(object sender, EventArgs e) {
            OpenFileDialog o = new OpenFileDialog();
            o.Filter = "Update Files(*.rbf;*.bin)|*.rbf;*.bin|rbf Files(*.rbf)|*.rbf|bin Files(*.bin)|*.bin";
            o.Multiselect = false;
            if (Directory.Exists(lastPath_RbfFile)) {
                o.InitialDirectory = lastPath_RbfFile;
            } else {
                o.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
            }
            if (o.ShowDialog() == DialogResult.OK) {
                lastPath_RbfFile = (new FileInfo(o.FileName)).DirectoryName;

                filePathTextBox.Text = o.FileName;
                rbfFileName = o.FileName;
                rbfSafeFileName = o.SafeFileName;

                string file_exname = (new FileInfo(o.FileName)).Extension.ToLower();
                if (file_exname.Equals(".rbf")) {
                    // 打开 .rbf 文件并读取内容
                    FileStream fs = File.OpenRead(rbfFileName);
                    BinaryReader reader = new BinaryReader(fs);
                    byte[] orignData = new byte[fs.Length];
                    orignData = reader.ReadBytes(orignData.Length);
                    typeLog(".rbf file read done. dataLength = " + orignData.Length);
                    rbfTextBox.Text = Tools.Byte2HexString4RBF(orignData);
                    rbfTextBox.Text += "----------------------File End----------------------\n";
                    showProDetail("", "FPGA");
                    FPGAradioButton.Checked = true;
                }
                if (file_exname.Equals(".bin")) {
                    // 打开 .bin 文件并读取内容
                    FileStream fs = File.OpenRead(rbfFileName);
                    BinaryReader reader = new BinaryReader(fs);
                    byte[] orignData = new byte[fs.Length];
                    orignData = reader.ReadBytes(orignData.Length);
                    typeLog(".bin file read done. dataLength = " + orignData.Length);
                    rbfTextBox.Text = Tools.Byte2HexString4RBF(orignData);
                    rbfTextBox.Text += "----------------------File End----------------------\n";
                    showProDetail("", "MCU");
                    MCUradioButton.Checked = true;
                }
            }
        }

        private void showProDetail(string target, string type) {
            lblProDetails.Text = string.Format("当前为{0}{1}程序", target, type);
        }

        // 清空 rbf 文件预览
        private void clearRBFTextButton_Click(object sender, EventArgs e) {
            rbfTextBox.Text = "";
        }

        // 重新读取 rbf 文件
        private void reReadButton_Click(object sender, EventArgs e) {
            if (!filePathTextBox.Text.Trim().Equals("")) {
                // 打开 .rbf 文件并读取内容
                FileStream fs = File.OpenRead(rbfFileName);
                BinaryReader reader = new BinaryReader(fs);
                byte[] orignData = new byte[fs.Length];
                orignData = reader.ReadBytes(orignData.Length);
                rbfTextBox.Text = Tools.Byte2HexString4RBF(orignData);
                rbfTextBox.Text += "----------------------File End----------------------\n";
            }
        }

        // 刷新 rbf 文件预览区
        private void refreshButton_Click(object sender, EventArgs e) {
            clearRBFTextButton_Click(null, null);
            reReadButton_Click(null, null);
        }

        // 全选按钮
        private void selectAllButton_Click(object sender, EventArgs e) {
            // 界面索引-[1,currentTestedNum], subCtrlInfoList索引-[0,currentTestedNum-1]
            for (int k = 0; k < currentTestedNum; k++) {
                DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)infoDataView.Rows[k + 1].Cells[1];
                checkCell.Value = true;
                ((SubEquInfo)deviceInfoList[k]).needUpdate = true;
                infoDataView.Rows[k + 1].DefaultCellStyle.BackColor = selectColor;
            }
        }

        // 全不选按钮
        private void selectNoneButton_Click(object sender, EventArgs e) {
            // 界面索引-[1,currentTestedNum], subCtrlInfoList索引-[0,currentTestedNum-1]
            for (int k = 0; k < currentTestedNum; k++) {
                DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)infoDataView.Rows[k + 1].Cells[1];
                checkCell.Value = false;
                ((SubEquInfo)deviceInfoList[k]).needUpdate = false;
                infoDataView.Rows[k + 1].DefaultCellStyle.BackColor = Color.White;
            }
        }

        // 反选按钮
        private void reverseButton_Click(object sender, EventArgs e) {
            // 界面索引-[1,currentTestedNum], subCtrlInfoList索引-[0,currentTestedNum-1]
            for (int k = 0; k < currentTestedNum; k++) {
                DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)infoDataView.Rows[k + 1].Cells[1];
                if ((bool)checkCell.Value) {
                    checkCell.Value = false;
                    ((SubEquInfo)deviceInfoList[k]).needUpdate = false;
                    infoDataView.Rows[k + 1].DefaultCellStyle.BackColor = Color.White;
                } else {
                    checkCell.Value = true;
                    ((SubEquInfo)deviceInfoList[k]).needUpdate = true;
                    infoDataView.Rows[k + 1].DefaultCellStyle.BackColor = selectColor;
                }
            }
        }

        // 关闭窗口
        private void UIForm_FormClosing(object sender, FormClosingEventArgs e) {
            string msg = "强制停止";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
            }

            if (updateButton.Text.Equals(msg) && !forceExit) {
                string msg1 = "升级操作正在进行中, 请先停止升级";
                if (LanguageOper.available == true) {
                    msg1 = LanguageOper.ReadValue(section, "msgStr.13");
                }

                DialogResult dr = MessageBoxEx.Show(this, msg1, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);

                e.Cancel = true;

                return;
            }
        }

        // 单元格被点击 - 1.选择要升级的分控/附属设备 2.复位控制器
        private void infoDataView_CellContentClick(object sender, DataGridViewCellEventArgs e) {
            // 选择要升级的分控： 界面索引-[1,currentTestedNum], subCtrlInfoList索引-[0,currentTestedNum-1]
            if (e.ColumnIndex == 1) {
                int rowIndex = e.RowIndex;

                if (rowIndex < 0) {
                    return;
                }

                DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)infoDataView.Rows[rowIndex].Cells[1];

                if ((bool)checkCell.EditedFormattedValue == true) {
                    ((SubEquInfo)deviceInfoList[rowIndex - 1]).needUpdate = true;
                    infoDataView.Rows[rowIndex].DefaultCellStyle.BackColor = selectColor;
                } else {
                    ((SubEquInfo)deviceInfoList[rowIndex - 1]).needUpdate = false;
                    infoDataView.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
                }
            }
                // 复位控制器
            else if (e.ColumnIndex == 5) {
                string msg = string.Format("确认复位 “设备 {0}”？", e.RowIndex);
                if (LanguageOper.available == true) {
                    msg = string.Format(LanguageOper.ReadValue(section, "msgStr.14"), e.RowIndex);

                }

                DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

                if (dr == DialogResult.Cancel) {
                    return;
                }

                // 复位操作
                int subDepth = e.RowIndex;	// 分控级联深度从 1 开始
                resetSubEquController(subDepth, true);
            }
        }

        // 单元格结束编辑 - 获取当前行最新的是否升级标记状态
        private void infoDataView_CellEndEdit(object sender, DataGridViewCellEventArgs e) {
            int rowIndex = e.RowIndex;

            DataGridViewCheckBoxCell checkCell = (DataGridViewCheckBoxCell)infoDataView.Rows[rowIndex].Cells[1];

            if ((bool)checkCell.EditedFormattedValue == true) {
                ((SubEquInfo)deviceInfoList[rowIndex - 1]).needUpdate = true;
                infoDataView.Rows[rowIndex].DefaultCellStyle.BackColor = selectColor;
            } else {
                ((SubEquInfo)deviceInfoList[rowIndex - 1]).needUpdate = false;
                infoDataView.Rows[rowIndex].DefaultCellStyle.BackColor = Color.White;
            }
        }

        // 在线升级按钮
        private void updateButton_Click(object sender, EventArgs e) {
            string msg = "强制停止";
            string msg1 = "升级正在进行中, 确认强制停止？";
            string msg2 = "请选择 .rbf 文件";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "str.1");
                msg1 = LanguageOper.ReadValue(section, "msgStr.15");
                msg2 = LanguageOper.ReadValue(section, "msgStr.16");
            }

            if (updateButton.Text.Equals(msg)) {
                DialogResult dr = MessageBoxEx.Show(this, msg1, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.Cancel) {
                    return;
                }

                baseCoreNet.forceStopUpdate();
                forceStopUpdate = true;

                // 升级操作后恢复界面按钮
                enableButtonsAfterUpdate();

                return;
            }

            // 选择 .rbf 文件
            if (filePathTextBox.Text.Trim().Equals("")) {
                if (rbfFileName.Trim().Equals("")) {
                    MessageBoxEx.Show(this, msg2, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }
            }

            if (updateSubEquDepth == null) {
                updateSubEquDepth = new ArrayList();
            } else {
                updateSubEquDepth.Clear();
            }

            for (int i = 0; i < currentTestedNum; i++) {
                if (((SubEquInfo)deviceInfoList[i]).needUpdate) {
                    updateSubEquDepth.Add(((SubEquInfo)deviceInfoList[i]).index);
                }
                refreshRowInfo(i + 1, 4, "--");
            }

            if (updateSubEquDepth.Count == 0) {
                string msg3 = "请选择要升级的设备";
                if (LanguageOper.available == true) {
                    msg3 = LanguageOper.ReadValue(section, "msgStr.25");
                }
                MessageBoxEx.Show(this, msg3, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // 在线升级线程
            Thread updateThread = null;
            if (FPGAradioButton.Checked) {
                // 串行模式
                if (updateMode == 0) {
                    updateThread = new Thread(updateProcess);
                }
                    // 并行模式 - 默认
                else if (updateMode == 1) {
                    updateThread = new Thread(updateProcess_parallet);
                }
                    // 全局模式
                else if (updateMode == 2) {
                    updateThread = new Thread(updateProcess_total);
                }
            } else if (MCUradioButton.Checked) {
                // 串行模式
                if (updateMode == 0) {
                    updateThread = new Thread(updatebinProcess);
                }
                    // 并行模式 - 默认
                else if (updateMode == 1) {
                    updateThread = new Thread(updatebinProcess_parallet);
                }
                    // 全局模式
                else if (updateMode == 2) {
                    updateThread = new Thread(updatebinProcess_total);
                }
            } else {
                MessageBox.Show("未确认升级文件类型，无法升级");
                return;
            }
            baseCoreNet.clearForceStopUpdate();
            forceStopUpdate = false;

            // 启动在线升级线程
            updateThread.IsBackground = true;
            updateThread.Start();

            // 升级操作前禁用界面按钮
            disableButtonsBeforeUpdate();
        }

        // 选择串行升级模式
        private void serialRadioButton_CheckedChanged(object sender, EventArgs e) {
            if (serialRadioButton.Checked) {
                updateMode = 0;
            }
        }

        // 选择并行升级模式
        private void paraRadioButton_CheckedChanged(object sender, EventArgs e) {
            if (paraRadioButton.Checked) {
                updateMode = 1;
            }
        }

        // 选择全局升级模式
        private void totalRadioButton_CheckedChanged(object sender, EventArgs e) {
            if (totalRadioButton.Checked) {
                updateMode = 2;
            }
        }

        // 配置时间间隔
        private void configTimeheckBox_CheckedChanged(object sender, EventArgs e) {
            if (configTimeheckBox.Checked) {
                eraseTimeTextBox.Enabled = true;
                updateTimeTextBox.Enabled = true;
                effectConfigButton.Enabled = true;
            } else {
                eraseTimeTextBox.Enabled = false;
                updateTimeTextBox.Enabled = false;
                effectConfigButton.Enabled = false;
            }
        }

        // 生效配置
        private void effectConfigButton_Click(object sender, EventArgs e) {
            try {
                int eraseTimeSpanNew = Convert.ToInt32(eraseTimeTextBox.Text.Trim());
                int updateTimeSpanNew = Convert.ToInt32(updateTimeTextBox.Text.Trim());
                int checkTimeSpanNew = Convert.ToInt32(checkTimeTextBox.Text.Trim());

                if (eraseTimeSpanNew < 0 || updateTimeSpanNew < 0 || checkTimeSpanNew < 0) {
                    string msg = "时间间隔不可为负";
                    if (LanguageOper.available == true) {
                        msg = LanguageOper.ReadValue(section, "msgStr.17");
                    }
                    throw new Exception(msg);
                }

                baseCoreNet.setEraseTimeSpan(eraseTimeSpanNew);
                baseCoreNet.setUpdateTimeSpan(updateTimeSpanNew);

                this.checkTimeSpan = checkTimeSpanNew;

                string s1 = "时间间隔设置成功";
                string s2 = string.Format("擦除间隔：{0} ms", eraseTimeSpanNew);
                string s3 = string.Format("在线升级发包间隔：{0} ms", updateTimeSpanNew);
                string s4 = string.Format("检查Flash发包间隔：{0} ms", checkTimeSpanNew);
                if (LanguageOper.available == true) {
                    s1 = LanguageOper.ReadValue(section, "msgStr.18");
                    s2 = string.Format(LanguageOper.ReadValue(section, "msgStr.19"), eraseTimeSpanNew);
                    s3 = string.Format(LanguageOper.ReadValue(section, "msgStr.20"), updateTimeSpanNew);
                    s4 = string.Format(LanguageOper.ReadValue(section, "msgStr.21"), checkTimeSpanNew);
                }
                MessageBoxEx.Show(this, s1 + "\n" + s2 + "\n" + s3 + "\n" + s4, tip, MessageBoxButtons.OK, MessageBoxIcon.Information);
            } catch (Exception ex) {
                string msg = "时间间隔设置失败：";
                if (LanguageOper.available == true) {
                    msg = LanguageOper.ReadValue(section, "msgStr.22");
                }
                MessageBoxEx.Show(this, msg + ex.Message, tip, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // 调试开关
        private void debugCheckBox_CheckedChanged(object sender, EventArgs e) {
            debugSwich = debugCheckBox.Checked;
        }

        // 升级操作前禁用界面按钮
        private void disableButtonsBeforeUpdate() {
            string text = "强制停止";
            if (LanguageOper.available == true) {
                text = LanguageOper.ReadValue(section, "updateButton.Text.0");
            }

            updateButton.Text = text;
            openButton.Enabled = false;
            selectAllButton.Enabled = false;
            selectNoneButton.Enabled = false;
            reverseButton.Enabled = false;
            clearLogButton.Enabled = false;
            serialRadioButton.Enabled = false;
            paraRadioButton.Enabled = false;
            totalRadioButton.Enabled = false;
            infoDataView.Enabled = false;
            if (configTimeheckBox.Checked) {
                effectConfigButton.Enabled = false;
            }
            forceInitialButton.Enabled = false;
            resetAllButton.Enabled = false;
            refreshSubInfoButton.Enabled = false;
            subRadioButton.Enabled = false;
        }

        // 升级操作后恢复界面按钮
        private void enableButtonsAfterUpdate() {
            string text = "升 级";
            if (LanguageOper.available == true) {
                text = LanguageOper.ReadValue(section, "updateButton.Text.1");
            }

            updateButton.Text = text;
            openButton.Enabled = true;
            selectAllButton.Enabled = true;
            selectNoneButton.Enabled = true;
            reverseButton.Enabled = true;
            clearLogButton.Enabled = true;
            serialRadioButton.Enabled = true;
            paraRadioButton.Enabled = true;
            totalRadioButton.Enabled = true;
            infoDataView.Enabled = true;
            if (configTimeheckBox.Checked) {
                effectConfigButton.Enabled = true;
            }
            forceInitialButton.Enabled = true;
            resetAllButton.Enabled = true;
            refreshSubInfoButton.Enabled = true;
            subRadioButton.Enabled = true;
        }

        // 强制进入底层程序
        private void forceInitialButton_Click(object sender, EventArgs e) {
            string text1 = "强制进入底层";
            string text2 = "取 消";
            string msg1 = "强制进入底层";
            string msg2 = "确认强制进入底层？";
            if (LanguageOper.available == true) {
                text1 = LanguageOper.ReadValue(section, "forceInitialButton.Text.0");
                text2 = LanguageOper.ReadValue(section, "forceInitialButton.Text.1");
                msg1 = LanguageOper.ReadValue(section, "str.10");
                msg2 = LanguageOper.ReadValue(section, "msgStr.23");
            }

            if (forceInitialButton.Text.Equals(text1)) {
                DialogResult dr = MessageBoxEx.Show(this, msg2, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.Cancel) {
                    return;
                }

                // 禁用在线检测、升级、全局复位按钮
                updateButton.Enabled = false;
                resetAllButton.Enabled = false;
                infoDataView.Enabled = false;

                // 显示设置包设置为黑屏（预存现有状态）
                DispConfigPacketPara dispConfigPacketPara = baseCoreNet.getDispConfigPacketPara();
                dispConfigPacketPara.Disp_Black = ParaState.ON;
                baseCoreNet.setDispConfigPacketPara(dispConfigPacketPara);

                forceInitialButton.Text = text2;

                this.Invoke(updateCurrentOperLabelDelegate, msg1);

                cancelForceInitial = false;
                Thread t = new Thread(forceInitial);
                t.IsBackground = true;
                t.Start();
            } else {
                // 启用在线检测、升级、全局复位按钮
                resetAllButton.Enabled = true;
                infoDataView.Enabled = true;

                // 显示设置包设置为正常
                DispConfigPacketPara dispConfigPacketPara = baseCoreNet.getDispConfigPacketPara();
                dispConfigPacketPara.Disp_Black = ParaState.OFF;
                baseCoreNet.setDispConfigPacketPara(dispConfigPacketPara);

                cancelForceInitial = true;	// 设置强制退出标记
                forceInitialButton.Text = text1;

                this.Invoke(updateCurrentOperLabelDelegate, "--");
            }
        }

        // 全局复位
        private void resetAllButton_Click(object sender, EventArgs e) {
            string msg = "确认全局复位？";
            string text = "已复位";
            if (LanguageOper.available == true) {
                msg = LanguageOper.ReadValue(section, "msgStr.24");
                text = LanguageOper.ReadValue(section, "str.9");
            }

            DialogResult dr = MessageBoxEx.Show(this, msg, tip, MessageBoxButtons.OKCancel, MessageBoxIcon.Question);

            if (dr == DialogResult.Cancel) {
                return;
            }

            byte[] dataBuff3 = new byte[256];
            for (int i = 0; i < 256; i++) {
                dataBuff3[i] = 0x0;
            }

            // 复位所有分控
            for (int k = currentTestedNum - 1; k >= 0; k--) {
                int subDepth = k + 1;
                baseCoreNet.writeSubMem(currentDeviceIndex, subDepth, 0x10000000, dataBuff3, false);

                SubEquInfo info = (SubEquInfo)deviceInfoList[subDepth - 1];
                info.firmwareVersion = text;
                this.Invoke(refreshRowInfoDelegate, subDepth, 3, text);
            }
        }

        // 更改分控/附属设备级联深度读取位置
        private void depthRadioButton2_CheckedChanged(object sender, EventArgs e) {
            if (depthRadioButton2.Checked) {
                baseCoreNet.setDepthReadPosition(DepthReadPos.Pos_59_61);
            } else {
                baseCoreNet.setDepthReadPosition(DepthReadPos.Pos_54_56);
            }
        }

        // 刷新设备信息
        private void refreshSubInfoButton_Click(object sender, EventArgs e) {
            deviceInfoList.Clear();
            int currentTestedNum_tmp = 0;
            List<ControlNode> nodeList = baseCoreNet.getControlNodeList();
            foreach (ControlNode node in nodeList) {
                if (target == DeviceType.SubControl && node.type == 1) {
                    currentTestedNum_tmp++;
                    SubEquInfo info = new SubEquInfo(currentTestedNum_tmp, false, node.version, node.mySubCtrlDepth + 1, DeviceType.SubControl);
                    deviceInfoList.Add(info);
                } else if (target == DeviceType.Equipment && node.type == 0) {
                    currentTestedNum_tmp++;
                    SubEquInfo info = new SubEquInfo(currentTestedNum_tmp, false, node.version, node.myEquipmentDepth + 1, DeviceType.Equipment);
                    deviceInfoList.Add(info);
                }
            }
            currentTestedNum = currentTestedNum_tmp;

            infoDataView.Invoke(updateDeviceDetailDelegate);
        }

        // 窗体加载后处理
        private void Form_SubUpdate_Load(object sender, EventArgs e) {
            refreshSubInfoButton.PerformClick();
        }

        // 类型选择
        private void FPGAradioButton_CheckedChanged(object sender, EventArgs e) {
            equRadioButton.Enabled = FPGAradioButton.Checked;
            testRadioButton.Enabled = FPGAradioButton.Checked;
            if (!equRadioButton.Enabled) {
                if (equRadioButton.Checked) {
                    subRadioButton.Checked = true;
                }
            }
            if (!testRadioButton.Enabled) {
                if (testRadioButton.Checked) {
                    appRadioButton.Checked = true;
                }
            }
        }

        #endregion
    }

    internal class SubEquInfo {
        public int id = -1;								// ID

        public int index = -1;							// 级联深度

        public DeviceType type = DeviceType.Unknown;	// 设备类型

        public bool needUpdate = false;					// 升级标识

        public string typeStr = "--";					// 显示的设备类型

        public string firmwareVersion = "--";			// 当前固件版本

        public string status = "--";					// 当前状态

        // 构造函数
        public SubEquInfo(int id, bool needUpdate, string firmwareVersion, int index, DeviceType type) {
            this.id = id;

            this.index = index;

            this.type = type;

            this.needUpdate = needUpdate;

            this.firmwareVersion = firmwareVersion;

            if (type == DeviceType.SubControl) {
                if (firmwareVersion.Contains("SL908") || firmwareVersion.Contains("SL909")) {
                    typeStr = "L9";
                } else {
                    typeStr = "Unknown";
                }
            } else if (type == DeviceType.Equipment) {
                typeStr = "Equ";
            }
        }
    }
}
